use std::collections::HashMap;
use std::fmt;
use std::fmt::{Display, Formatter};
use tracing::error;
use crate::util::date_util;

#[derive(Debug, Clone, Copy)]
pub enum HttpStatusCode {
    Ok,
    BadRequest,
    Redirect,
    NotFound,
    Forbidden,
    ServerError,
}

impl HttpStatusCode {
    // 获取状态码和描述文本
    pub fn value(&self) -> (String, String) {
        match self {
            HttpStatusCode::Ok => ("200".to_string(), "OK".to_string()),
            HttpStatusCode::BadRequest => ("400".to_string(), "Bad Request".to_string()),
            HttpStatusCode::Redirect => ("301".to_string(), "Redirect".to_string()),
            HttpStatusCode::NotFound => ("404".to_string(), "Not Found".to_string()),
            HttpStatusCode::Forbidden => ("403".to_string(), "Forbidden".to_string()),
            HttpStatusCode::ServerError => ("500".to_string(), "Internal Server Error".to_string()),
        }
    }

    // 如果只需要状态码
    pub fn code(&self) -> String {
        self.value().0
    }

    // 如果只需要描述文本
    pub fn text(&self) -> String {
        self.value().1
    }
}

#[derive(Debug)]
pub struct HttpResponse {
    pub status_code: String,
    pub status_text: String,
    pub headers: HashMap<String, String>,
    pub body: Vec<u8>, // 修改: 将 body 类型从 String 改为 Vec<u8>
}

impl HttpResponse {
    pub fn new(
        status_code: HttpStatusCode,
        headers: HashMap<String, String>,
        body: Vec<u8>, // 修改: 将 body 类型从 String 改为 Vec<u8>
    ) -> Self {
        HttpResponse {
            status_code: status_code.code(),
            status_text: status_code.text(),
            headers,
            body,
        }
    }

    pub fn new_empty_body(status_code: HttpStatusCode, headers: HashMap<String, String>) -> Self {
        HttpResponse {
            status_code: status_code.code(),
            status_text: status_code.text(),
            headers,
            body: Vec::new(), // 修改: 将 body 类型从 String 改为 Vec<u8>
        }
    }

    pub fn common_headers(headers: &mut HashMap<String, String>) {
        // 修改Data响应头为当前日期格式
        headers.insert("Server".to_string(), "RustHttpServer/1.0".to_string());
        headers.insert("Connection".to_string(), "keep-alive".to_string());
        headers.insert("Data".to_string(), date_util::get_current_date()); // 使用日期工具函数
    }

    pub fn ok(response: &mut HttpResponse) { // 修改: 将 body 类型从 String 改为 Vec<u8>
        response.status_code = HttpStatusCode::Ok.code();
        response.status_text = HttpStatusCode::Ok.text();
    }

    pub fn ok_no_body(response: &mut HttpResponse) {

        let mut headers = &mut response.headers;
        HttpResponse::common_headers(&mut headers);


        headers.insert("Content-Type".to_string(), "text/plain".to_string());
        headers.insert("Content-Length".to_string(), "".len().to_string());

        response.status_code = HttpStatusCode::Ok.code();
        response.status_text = HttpStatusCode::Ok.text();
    }

    pub fn ok_redirect(location: String, response: &mut HttpResponse) {

        let mut headers = &mut response.headers;
        HttpResponse::common_headers(&mut headers);
        headers.insert("Location".to_string(), location);


        headers.insert("Content-Type".to_string(), "text/plain".to_string());
        headers.insert("Content-Length".to_string(), "".len().to_string());
        // HttpResponse::new(HttpStatusCode::Redirect, headers, Vec::new()) // 修改: 将 body 类型从 String 改为 Vec<u8>
        response.status_code = HttpStatusCode::Redirect.code();
        response.status_text = HttpStatusCode::Redirect.text();
    }

    pub fn bad_request(response: &mut HttpResponse) {
        let mut headers = &mut response.headers;
        HttpResponse::common_headers(&mut headers);
        response.body = Vec::new();
        response.status_code = HttpStatusCode::BadRequest.code();
        response.status_text = HttpStatusCode::BadRequest.text();
    }

    pub fn not_found(response: &mut HttpResponse) {
        let mut headers = &mut response.headers;
        HttpResponse::common_headers(&mut headers, );
        headers.insert("Content-Length".to_string(), "0".to_string()); // 修改: 将内容长度设置为 "0"
        headers.insert("Content-Type".to_string(), "text/plain".to_string());
        // 修改: 将 body 类型从 String 改为 Vec<u8>
        response.body = Vec::new();
        response.status_code = HttpStatusCode::NotFound.code();
        response.status_text = HttpStatusCode::NotFound.text();
    }

    pub fn ok_with_content_type(content: String, content_type: &str, response: &mut HttpResponse) -> HttpResponse {
        let mut headers = HashMap::new();
        HttpResponse::common_headers(&mut headers, );
        headers.insert("Content-Type".to_string(), content_type.to_string());
        headers.insert("Content-Length".to_string(), content.len().to_string());

        HttpResponse {
            status_code: HttpStatusCode::Ok.code(),
            status_text: HttpStatusCode::Ok.text(),
            headers,
            body: content.into_bytes(), // 修改: 将 content 转换为 Vec<u8>
        }
    }

    pub fn ok_with_binary(content: Vec<u8>, content_type: &str) -> HttpResponse {
        let mut headers = HashMap::new();
        HttpResponse::common_headers(&mut headers, );
        headers.insert("Content-Type".to_string(), content_type.to_string());
        headers.insert("Content-Length".to_string(), content.len().to_string());
        headers.insert("Cache-Control".to_string(), "no-cache".to_string());

        HttpResponse {
            status_code: HttpStatusCode::Ok.code(),
            status_text: HttpStatusCode::Ok.text(),
            headers,
            body: content,
        }
    }

    pub fn forbidden(response: &mut HttpResponse) -> HttpResponse {
        let mut headers = HashMap::new();
        HttpResponse::common_headers(&mut headers, );
        let body = Vec::new(); // 修改: 将 body 类型从 String 改为 Vec<u8>

        headers.insert("Content-Length".to_string(), body.len().to_string());
        headers.insert("Content-Type".to_string(), "text/plain".to_string());

        HttpResponse {
            status_code: HttpStatusCode::Forbidden.code(),
            status_text: HttpStatusCode::Forbidden.text(),
            headers,
            body,
        }
    }

    pub fn server_error(response: &mut HttpResponse) {
        let mut headers = &mut response.headers;
        HttpResponse::common_headers(&mut headers, );
        let body = Vec::new(); // 修改: 将 body 类型从 String 改为 Vec<u8>

        headers.insert("Content-Type".to_string(), "text/plain".to_string());
        headers.insert("Content-Length".to_string(), body.len().to_string());

        response.body = body;
        response.status_text = HttpStatusCode::ServerError.text();
        response.status_code = HttpStatusCode::ServerError.code();
    }

    // 将 HttpResponse 转换为字节数组
    pub fn to_bytes(&self) -> Vec<u8> {
        let mut bytes = Vec::new();

        // 写入状态行
        bytes.extend(format!("HTTP/1.1 {} {}\r\n", self.status_code, self.status_text).as_bytes());

        // 写入头部信息
        for (key, value) in &self.headers {
            bytes.extend(format!("{}: {}\r\n", key, value).as_bytes());
        }

        // 写入空行分隔头部和响应体
        bytes.extend(b"\r\n");

        // 写入响应体
        bytes.extend(&self.body);

        bytes
    }
}


impl Display for HttpStatusCode {
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        let status_str = match self {
            HttpStatusCode::Ok => "200 OK",
            HttpStatusCode::BadRequest => "400 Bad Request",
            HttpStatusCode::NotFound => "404 Not Found",
            HttpStatusCode::Redirect => "301 Redirect",
            HttpStatusCode::Forbidden => "403 Forbidden",
            HttpStatusCode::ServerError => "500 Internal Server Error",
        };
        write!(f, "{}", status_str)
    }
}

// 实现 HttpResponse 的 Display 接口
impl Display for HttpResponse {
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        // 写入状态行
        writeln!(f, "HTTP/1.1 {} {}\r\n", self.status_code, self.status_text)?;

        // 写入头部信息
        for (key, value) in &self.headers {
            writeln!(f, "{}: {}\r\n", key, value)?;
        }

        // 写入空行分隔头部和响应体
        writeln!(f)?;

        // 写入响应体（仅限文本内容）
        if let Ok(body_str) = String::from_utf8(self.body.clone()) {
            write!(f, "{}", body_str)?;
        }

        Ok(())
    }
}